﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Utilities;
using System.Web.Security;
using Microsoft.SharePoint.Administration;
using System.Text;
using Microsoft.SharePoint.Administration.Claims;
using System.Collections.Generic;

namespace AIS.SharePoint.AspNetFBA.Layouts.AIS.SharePoint.AspNetFBA
{
    public partial class UserCreate : LayoutsPageBase, System.Web.UI.IPostBackEventHandler
    {
        private const string _SAVECOMMAND = "Save";
        private const string _CANCELCOMMAND = "Cancel";

        // Structure to group user data
        public struct UserData
        {
            public string FullName;
            public string UserName;
            public string EMail;
            public string Password;
            public string SiteURL;
            public string SecurityQuestion;
            public string SecurityAnswer;
        }

        /// <summary>
        /// Required rights for the page
        /// </summary>
        protected override SPBasePermissions RightsRequired
        {
            get
            {
                return SPBasePermissions.ManagePermissions;
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            try
            {
                // Create ribbon events for each supported command
                List<IRibbonCommand> CommandList = new List<IRibbonCommand>();
                CommandList.Add(new SPRibbonCommand("AIS.SharePoint.AspNetFAB.Ribbon.Edit.Commit.Publish", "SaveClicked()", "true"));
                CommandList.Add(new SPRibbonPostBackCommand("AIS.SharePoint.AspNetFAB.Ribbon.Edit.Commit.Cancel", this, _CANCELCOMMAND, null, "true"));

                Code.Ribbon.ActivateRibbon(this.Page, CommandList, sectionBottomButtons, Code.RibbonType.CommitRibbon);

                base.OnPreRender(e);
            }
            catch (Exception ex)
            {
                Code.Log.Error(ex, Microsoft.SharePoint.Administration.TraceSeverity.High, Code.Log.Category.Processing);
                SPUtility.TransferToErrorPage(ex.Message);
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                CheckRights();

                Code.ConfigSettings Settings = new Code.ConfigSettings(SPContext.Current.Web);

                if (!IsPostBack)
                {
                    // Random password generation
                    if (Settings.AutoGenNewUserPassword)
                    {
                        string Password = System.Web.Security.Membership.GeneratePassword(10, 4);
                        txtUserPassword.Text = Password;
                        txtUserPasswordConfirm.Text = Password;
                    }

                    // Populate and display roles
                    chkRoleList.DataSource = Roles.GetAllRoles();
                    chkRoleList.DataBind();
                    sectionRoles.Visible = chkRoleList.Items.Count > 0;
                    ((Microsoft.SharePoint.WebControls.InputFormSection)sectionRoles).Collapsed = (chkRoleList.Items.Count > 10);

                    // Populate and display groups groups
                    chkGroupList.DataSource = Web.Groups;
                    chkGroupList.DataBind();
                    sectionGroups.Visible = chkGroupList.Items.Count > 0;
                    ((Microsoft.SharePoint.WebControls.InputFormSection)sectionGroups).Collapsed = (chkGroupList.Items.Count > 10);

                    // Default the site URL
                    txtSiteURL.Text = SPContext.Current.Web.Url;

                    txtFullName.Focus();
                }

                sectionAutoWelcome.Visible = Settings.AutoGenWelcomeEMail;
                sectionWelcomeEMail.Visible = (!Settings.AutoGenWelcomeEMail || chkDoNotSendAutoWelcome.Checked);
                sectionWelcomeEMailDetails.Visible = ((!Settings.AutoGenWelcomeEMail || chkDoNotSendAutoWelcome.Checked) && chkSendWelcomeEMail.Checked);
                sectionSecurityQuestion.Visible = Membership.RequiresQuestionAndAnswer;
            }
            catch (System.UnauthorizedAccessException)
            {
                SPUtility.Redirect(SPUtility.AccessDeniedPage, SPRedirectFlags.RelativeToLayoutsPage, Context);
            }
            catch (Exception ex)
            {
                Code.Log.Error(ex, Microsoft.SharePoint.Administration.TraceSeverity.High, Code.Log.Category.Rendering);
                SPUtility.TransferToErrorPage(ex.Message);
            }
        }

        /// <summary>
        /// Process a new user
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnOK_Click(object sender, EventArgs e)
        {
            Save();
        }

        public void RaisePostBackEvent(string eventArgument)
        {
            try
            {
                SPRibbonPostBackEvent RibbonEvent = SPRibbonPostBackCommand.DeserializePostBackEvent(eventArgument);
                string EventId = RibbonEvent.Id;

                if (string.Equals(EventId, _SAVECOMMAND, StringComparison.InvariantCultureIgnoreCase))
                {
                    Save();
                }
                else if (string.Equals(EventId, _CANCELCOMMAND, StringComparison.InvariantCultureIgnoreCase))
                {
                    Code.Common.ClosePage();
                }
            }
            catch (Exception ex)
            {
                Code.Log.Error(ex, Microsoft.SharePoint.Administration.TraceSeverity.High, Code.Log.Category.Processing);
                SPUtility.TransferToErrorPage(ex.Message);
            }
        }

        private void Save()
        {
            try
            {
                // Validate page
                Page.Validate();
                if (!Page.IsValid) { return; }

                Code.ConfigSettings Settings = new Code.ConfigSettings(SPContext.Current.Web);

                MembershipUser NewUser = null;
                MembershipCreateStatus Status;
                bool IsValid = false;
                string Message = null;

                UserData UserData = new UserCreate.UserData();
                UserData.UserName = txtUserName.Text.Trim();
                UserData.FullName = txtFullName.Text.Trim();
                UserData.Password = txtUserPassword.Text.Trim();
                UserData.EMail = txtUserEMail.Text.Trim();
                UserData.SiteURL = txtSiteURL.Text.Trim();
                UserData.SecurityQuestion = Membership.RequiresQuestionAndAnswer ? txtSecurityQuestion.Text.Trim() : null;
                UserData.SecurityAnswer = Membership.RequiresQuestionAndAnswer ? txtSecurityAnswer.Text.Trim() : null;

                // Attempt to create the user
                NewUser = Membership.CreateUser(UserData.UserName
                    , UserData.Password
                    , UserData.EMail
                    , UserData.SecurityQuestion
                    , UserData.SecurityAnswer
                    , true
                    , out Status);

                // Validate user creation
                #region User account creation status handling
                switch (Status)
                {
                    case MembershipCreateStatus.Success:
                        IsValid = true;
                        break;

                    case MembershipCreateStatus.DuplicateEmail:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_DuplicateEMail");
                        break;

                    case MembershipCreateStatus.DuplicateProviderUserKey:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_DuplicateProvider");
                        break;

                    case MembershipCreateStatus.DuplicateUserName:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_DuplicateUserName");
                        break;

                    case MembershipCreateStatus.InvalidAnswer:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_InvalidSecurityAnswer");
                        break;

                    case MembershipCreateStatus.InvalidEmail:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_InvalidEMail");
                        break;

                    case MembershipCreateStatus.InvalidPassword:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_InvalidPassword");
                        break;

                    case MembershipCreateStatus.InvalidProviderUserKey:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_InvalidProviderKey");
                        break;

                    case MembershipCreateStatus.InvalidQuestion:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_InvalidQuestion");
                        break;

                    case MembershipCreateStatus.InvalidUserName:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_InvalidUserName");
                        break;

                    case MembershipCreateStatus.ProviderError:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_ProviderError");
                        break;

                    case MembershipCreateStatus.UserRejected:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_UserRejected");
                        break;

                    default:
                        Message = Code.Common.GetLocalizedResource("$Resources:Page_UserCreate_UnknownError");
                        break;
                }
                #endregion

                if (!IsValid)
                {
                    lblErrorMessage.Text = Message;
                }

                if (IsValid)
                {
                    // process roles
                    foreach (System.Web.UI.WebControls.ListItem RoleItem in chkRoleList.Items)
                    {
                        if (RoleItem.Selected)
                        {
                            Roles.AddUserToRole(UserData.UserName, RoleItem.Value);
                        }
                    }

                    // process groups
                    Code.Claims ClaimsHandler = new Code.Claims();
                    foreach (System.Web.UI.WebControls.ListItem GroupItem in chkGroupList.Items)
                    {
                        if (GroupItem.Selected)
                        {
                            SPGroup Group = Web.Groups[GroupItem.Value];
                            if (Group != null)
                            {
                                SPClaim UserClaim = ClaimsHandler.GetClaimForUserName(UserData.UserName);
                                if (UserClaim != null)
                                {
                                    Group.AddUser(SPClaimProviderManager.Local.EncodeClaim(UserClaim), UserData.EMail, UserData.FullName, "");
                                }
                            }
                        }
                    }
                }

                // Final processing and e-mail generation
                if (IsValid)
                {
                    if (!chkDoNotSendAutoWelcome.Checked && Settings.AutoGenWelcomeEMail) 
                    {
                        Code.Common.SendEMail(UserData.EMail, Settings.WelcomeEMailSubject, Settings.WelcomeEMailBody, UserData.UserName, UserData.FullName, UserData.Password, UserData.SiteURL);
                    }

                    if (chkSendWelcomeEMail.Checked)
                    {
                        SPUtility.SendEmail(SPContext.Current.Web, true, false, UserData.EMail, txtWelcomeEMailSubject.Text, txtWelcomeEmailBody.Text);
                    }

                    Code.Common.ClosePage();
                }
            }
            catch (Exception ex)
            {
                Code.Log.Error(ex, Microsoft.SharePoint.Administration.TraceSeverity.High, Code.Log.Category.Processing);
                SPUtility.TransferToErrorPage(ex.Message);
            }
        }
    }
}
